from os import walk
from pathlib import Path


class Source:
    def __init__(self, name, root):
        self.name = name
        self.root = Path(root)

    def filter(self, root, path):
        return True

    def walk(self):
       for root, dirs, files in walk(self.root):
            for path in files:
                yield root, path

    @property
    def files(self):
        return [
            path
            for root, path in self.walk()
            if self.filter(root, path)
        ]


class File:
    def __init__(self, source, path):
        self.source = source
        self.path = path

    @property
    def full(self):
        return self.source.root / self.path

    @property
    def label(self):
        return f'{self.source.name} {self.path}'

    def grep(self, line_filter, nb_lines):
        try:
            content = open(self.full).read()
            lines = content.split('\n')
            for idx, line in enumerate(lines):
                if line_filter(line):
                    break
            else:
                return False
            self.idx = idx
            self.first = idx-10 if idx > 10 else 0
            last = self.first + nb_lines
            self.selection = '\n'.join(lines[:last])
            return True
        except Exception as x:
            self.selection = f'{x}'
            return False


class Files:
    def __init__(self, sources, Greper):
        self.files = [
            Greper(source, path)
            for source in sources
            for path in source.files
        ]
        self.filtered = None

    def filter(self, line_filter, nb_lines):
        self.filtered = [
            file
            for file in self.files
            if file.grep(line_filter, nb_lines)
        ]
        return self.filtered

    @property
    def labels(self):
        return [
            file.label
            for file in self.filtered
        ]
